//
// Created by 伍泉 on 2024/6/7.
//

#ifndef HELLOFFMPEG_FFMPEGWRAPPER_H
#define HELLOFFMPEG_FFMPEGWRAPPER_H
extern "C" {
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libavutil/opt.h"
#include "libavutil/channel_layout.h"
#include "libavutil/timestamp.h"
}

class FFmpegWrapper {
public:
    FFmpegWrapper();
    ~FFmpegWrapper();

    bool decode(const char *inputFilename, const char *videoOutputFilename, const char *audioOutputFilename);
    bool encode(const char *videoInputFilename, const char *audioInputFilename, const char *outputFilename);

    bool convertAudioToAAC(const char *inputFilename, const char *outputFilename);
    bool convertVideoToH264(const char *inputFilename, const char *outputFilename);

    void initFFmpeg();
    void cleanup();

    void decodeVideo(AVCodecContext *avCodecContext, AVFrame *avFrame, AVPacket *pkt, const char *filename);
    void decodeAudio(AVCodecContext *avCodecContext, AVPacket *pkt, AVFrame *avFrame, FILE *outfile);
    void saveYUV(AVFrame *avFrame, char *filename);
    int getSampleFmtFromName(const char **fmt, enum AVSampleFormat sample_fmt);

private:

    AVFormatContext* openInputFile(const char *filename);
    AVCodecContext* createCodecContext(AVCodecParameters *params, const AVCodec *codec);
    bool writeDecodedFrameToFile(AVFrame *frame, FILE *videoFile, FILE *audioFile);
    bool openOutputFile(const char *filename, AVFormatContext **outputFormatContext);
    void closeFileResources(AVFormatContext *formatContext, AVCodecContext *decoderContext, AVCodecContext *encoderContext, AVStream *outStream);
};



#endif //HELLOFFMPEG_FFMPEGWRAPPER_H
